package com.rising.face.suanfa.threadprint2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: rising
 * @Description:
 * 给定一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9...., 15]，要求遍历数组，
 * 遇到可以同时被3和5整除的数字，打印C；
 * 遇到仅能被5整除的数字，打印B；
 * 遇到仅能被3整除的数字，打印A；
 * 其他打印数字本身；
 * 要求四个线程，每一个线程执行一个打印方法。
 * @Date: create in 2021/2/6 22:01
 */
public class ThreadPrint2 implements Runnable{

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    //遍历总数
    private volatile int count = 0;

    private int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

    private String threadName(int element) {
        if (element % 15 == 0) {
            return "C";
        } else if (element % 5 == 0) {
            return "B";
        } else if (element % 3 == 0) {
            return "A";
        } else {
            return "D";
        }
    }

    public void print() {
        lock.lock();
        try {
            //数组遍历完则结束
            bk:while (count < array.length) {
                //当前线程名字不匹配，则阻塞
                while (!Thread.currentThread().getName().equals(threadName(array[count]))) {
                    condition.await();
                    if (count >= array.length) {
                        break bk;
                    }
                }
                //执行打印
                System.out.println("线程" + Thread.currentThread().getName() + "打印：" +
                        (threadName(array[count]).equals("D") ? array[count] : threadName(array[count])));
                count++;
                condition.signalAll();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ThreadPrint2 data = new ThreadPrint2();
        new Thread(data, "D").start();
        new Thread(data, "C").start();
        new Thread(data, "B").start();
        new Thread(data, "A").start();
    }

    @Override
    public void run() {
        print();
    }
}
